import React, { Component } from 'react';
import PasswordManager from './js/passwordManager/passwordManager.js';
import PasswordCapture from './js/passwordManager/PasswordCapture.js';
import TabBar from './js/navbar/tabBar';
import SearchBar from './js/navbar/searchbar/searchbar.js';
import settings from './js/util/settings/settings.js';
import autofill from './js/autofillSetup.js';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import webviews from './js/webviews.js';
import * as store from './reducers/partsSlice';
import { connect } from 'react-redux';
import us from './js/userscripts.js';
import places from './js/places/places';
import searchEngine from './js/util/searchEngine.js';
import userscripts from './js/userscripts.js';
import remoteMenu from './js/remoteMenuRenderer.js';
import { db } from './js/util/database.js';
const ipc = window.require('electron').ipcRenderer
let windowIsMaximized = false; // affects navbar height on Windows
let windowIsFullscreen = false;
const electron = window.require('electron')
const clipboard = electron.clipboard;
const throttle = function (fn, threshhold, scope) {
  threshhold || (threshhold = 250);
  var last, deferTimer;
  return () => {
    var context = scope || this;
    var now = +new Date();
    var args = arguments;
    if (last && now < last + threshhold) {
      // hold on to it
      clearTimeout(deferTimer);
      deferTimer = setTimeout(() => {
        last = now;
        fn.apply(context, args);
      }, threshhold);
    } else {
      last = now;
      fn.apply(context, args);
    }
  };
};

const darkTheme = createTheme({
  components: {
    MuiTab: {
      styleOverrides:
        { root: { "&.Mui-selected": { color: "white" } } }
    }
  }
});

class Browser extends React.Component {
  constructor() {
    super();
    this.ref_target = React.createRef();
    this.menuData = null;
  }
  update_goback=(tabid, url)=>{
    console.log("update_goback------------------")
    console.log(url);
    let tabs = this.props.state.tabs;
    let tab_value = this.props.state.tab_value;
    // // console.log(state.tabs)
    let tab = tabs[tab_value];
    // console.log(tab);
    if(!tab) return;
    if (!tab.url) {
      this.props.dispatch(store.partsSlice.actions.GOBACK_DISABLE(true));
      return;
    }
    db.places
      .where('url')
      .equals(tab.url)
      .first(item => {
        if (item && item.isBookmarked) {
          this.props.dispatch(store.partsSlice.actions.CLICK_STAR(true));
        } else {
          this.props.dispatch(store.partsSlice.actions.CLICK_STAR(false));
        }
      });
    webviews.callAsync(
      tab.id,
      'canGoBack',
      (err, canGoBack) => {
        if (err) {
          return;
        }
        this.props.dispatch(store.partsSlice.actions.GOBACK_DISABLE(!canGoBack));
      }
    );
    webviews.callAsync(
      tab.id,
      'canGoForward',
      (err, canGoForward) => {
        if (err) {
          return;
        }
        this.props.dispatch(store.partsSlice.actions.GOFORWARD_DISABLE(!canGoForward));
      }
    );
  }
  openURL = (url, event) => {
    this.props.dispatch(store.partsSlice.actions.OPEN_URL(url));
  };
  showMenu = (tab, data, extraData) => {
    let tabid = tab.id;
    let url = tab.url;
    // data comes from a context-menu event
    console.log('webviewMenu showMenu');
    var currentTab = tab;

    var menuSections = [];

    const openInBackground = !settings.get('openTabsInForeground');

    /* Picture in Picture */

    if (extraData.hasVideo) {
      menuSections.push([
        {
          label: 'pictureInPicture',
          click: () => {
            webviews.callAsync(tabid, 'send', [
              'enterPictureInPicture',
              { x: data.x, y: data.y },
            ]);
          },
        },
      ]);
    }

    /* Spellcheck */

    if (data && data.misspelledWord) {
      var suggestionEntries = data.dictionarySuggestions
        .slice(0, 3)
        .map((suggestion) => {
          return {
            label: suggestion,
            click: () => {
              webviews.callAsync(
                tabid,
                'replaceMisspelling',
                suggestion
              );
            },
          };
        });

      // https://www.electronjs.org/docs/api/session#sesaddwordtospellcheckerdictionaryword
      // "This API will not work on non-persistent (in-memory) sessions"
      // if (!currentTab.private) {
      //   suggestionEntries.push({
      //     label: l('addToDictionary'),
      //     click: () => {
      //       //todo
      //       // remote.session.defaultSession.addWordToSpellCheckerDictionary(data.misspelledWord)
      //     },
      //   });
      // }

      if (suggestionEntries.length > 0) {
        menuSections.push(suggestionEntries);
      }
    }

    /* links */

    var link = data.linkURL;

    // show link items for embedded frames, but not the top-level page (which will also be listed as a frameURL)
    if (!link && data.frameURL && data.frameURL !== url) {
      link = data.frameURL;
    }

    if (link === 'about:srcdoc') {
      /* srcdoc is used in reader view, but it can't actually be opened anywhere outside of the reader page */
      link = null;
    }

    var mediaURL = data.srcURL;

    if (link) {
      var linkActions = [
        {
          label: link.length > 60 ? link.substring(0, 60) + '...' : link,
          enabled: false,
        },
      ];

      if (!currentTab.private) {
        linkActions.push({
          label: 'openInNewTab',
          click: () => {
            this.props.dispatch(store.partsSlice.actions.ADD_TAB({ url: link }))
            // browserUI.addTab(window.tasklist.task.tabs.add({ url: link }), {
            //   enterEditMode: false,
            //   openInBackground: openInBackground,
            // });
          },
        });
      }

      // linkActions.push({
      //   label: l('openInNewPrivateTab'),
      //   click: function () {
      //     this.props.dispatch(store.partsSlice.actions.ADD_TAB({ url: link }))
      //     // browserUI.addTab(window.tasklist.task.tabs.add({ url: link, private: true }), {
      //     //   enterEditMode: false,
      //     //   openInBackground: openInBackground,
      //     // });
      //   },
      // });

      linkActions.push({
        label: 'saveLinkAs',
        click: () => {
          //todo
          // remote.getCurrentWebContents().downloadURL(link)
          webviews.callAsync(tabid, 'downloadURL', link);
        },
      });

      menuSections.push(linkActions);
    } else if (mediaURL && data.mediaType === 'image') {
      /* images */
      /* we don't show the image actions if there are already link actions, because it makes the menu too long and because the image actions typically aren't very useful if the image is a link */

      var imageActions = [
        {
          label:
            mediaURL.length > 60 ? mediaURL.substring(0, 60) + '...' : mediaURL,
          enabled: false,
        },
      ];

      imageActions.push({
        label: 'viewImage',
        click: () => {
          webviews.update(tabid, mediaURL);
        },
      });

      if (!currentTab.private) {
        imageActions.push({
          label: 'openImageInNewTab',
          click: () => {
            this.props.dispatch(store.partsSlice.actions.ADD_TAB({ url: mediaURL }))
          },
        });
      }


      menuSections.push(imageActions);

      menuSections.push([
        {
          label: l('saveImageAs'),
          click: () => {
            webviews.callAsync(tabid, 'downloadURL', mediaURL);
            // this.props.dispatch(store.partsSlice.actions.DOWNLOAD({ url: mediaURL }))
          },
        },
      ]);
    }

    /* selected text */

    var selection = data.selectionText;

    if (selection) {
      var textActions = [
        {
          label: 'searchWith'.replace('%s', searchEngine.getCurrent().name),
          click: () => {
            this.props.dispatch(store.partsSlice.actions.ADD_TAB({
              url: searchEngine
                .getCurrent()
                .searchURL.replace('%s', encodeURIComponent(selection))
            }));
          },
        },
      ];
      menuSections.push(textActions);
    }

    var clipboardActions = [];

    if (mediaURL && data.mediaType === 'image') {
      clipboardActions.push({
        label: 'copy',
        click: () => {
          webviews.callAsync(tabid, 'copyImageAt', [
            data.x,
            data.y,
          ]);
        },
      });
    } else if (selection) {
      clipboardActions.push({
        label: 'copy',
        click: () => {
          webviews.callAsync(tabid, 'copy');
        },
      });
    }

    if (data.editFlags && data.editFlags.canPaste) {
      clipboardActions.push({
        label: 'paste',
        click: () => {
          webviews.callAsync(tabid, 'paste');
        },
      });
    }

    if (link || (mediaURL && !mediaURL.startsWith('blob:'))) {
      if (link && link.startsWith('mailto:')) {
        var ematch = link.match(/(?<=mailto:)[^\?]+/);
        if (ematch) {
          clipboardActions.push({
            label: 'copyEmailAddress',
            click: () => {
              clipboard.writeText(ematch[0]);
            },
          });
        }
      } else {
        clipboardActions.push({
          label: 'copyLink',
          click: () => {
            clipboard.writeText(link || mediaURL);
          },
        });
      }
    }

    if (clipboardActions.length !== 0) {
      menuSections.push(clipboardActions);
    }

    var navigationActions = [
      {
        label: 'goBack',
        click: () => {
          try {
            webviews.goBackIgnoringRedirects(tabid);
          } catch (e) { }
        },
      },
      {
        label: 'goForward',
        click: () => {
          try {
            webviews.callAsync(tabid, 'goForward');
          } catch (e) { }
        },
      },
    ];

    menuSections.push(navigationActions);

    /* inspect element */
    menuSections.push([
      {
        label: 'inspectElement',
        click: () => {
          webviews.callAsync(tabid, 'inspectElement', [
            data.x || 0,
            data.y || 0,
          ]);
        },
      },
    ]);

    /* Userscripts */

    var contextMenuScripts = userscripts
      .getMatchingScripts(url)
      .filter((script) => {
        if (
          script.options['run-at'] &&
          script.options['run-at'].includes('context-menu')
        ) {
          return true;
        }
      });

    if (contextMenuScripts.length > 0) {
      var scriptActions = [
        {
          label: 'runUserscript',
          enabled: false,
        },
      ];
      contextMenuScripts.forEach((script) => {
        scriptActions.push({
          label: script.name,
          click: () => {
            userscripts.runScript(tabid, script);
          },
        });
      });
      menuSections.push(scriptActions);
    }

    // Electron's default menu position is sometimes wrong on Windows with a touchscreen
    // https://github.com/minbrowser/min/issues/903
    var offset = webviews.getViewBounds();
    remoteMenu.open(menuSections, data.x + offset.x, data.y + offset.y);
  }
  // componentWillUnmount(){
  //   this.props.dispatch(store.partsSlice.actions.SAVE());
  // }
  componentDidMount() {
    const ro = new ResizeObserver((entries, observer) => {
      webviews.resize2(entries[0].contentRect.height);
    });
    us.initialize();
    window.addEventListener(
      'resize------------------',
      throttle(() => {
        console.log("resize")
        // if (webviews.placeholderRequests.length > 0) {
        //   // can't set view bounds if the view is hidden
        //   return;
        // }
        webviews.resize();
      }, 75)
    );

    // leave HTML fullscreen when leaving window fullscreen
    ipc.on('leave-full-screen', () => {
      // electron normally does this automatically (https://github.com/electron/electron/pull/13090/files), but it doesn't work for BrowserViews
      for (var view in webviews.viewFullscreenMap) {
        if (webviews.viewFullscreenMap[view]) {
          webviews.callAsync(
            view,
            'executeJavaScript',
            'document.exitFullscreen()'
          );
        }
      }
    });

    webviews.bindEvent('enter-html-full-screen', (tabid) => {
      webviews.viewFullscreenMap[tabid] = true;
      webviews.resize();
    });

    webviews.bindEvent('leave-html-full-screen', (tabid) => {
      webviews.viewFullscreenMap[tabid] = false;
      webviews.resize();
    });

    ipc.on('maximize', () => {
      windowIsMaximized = true;
      webviews.resize();
    });

    ipc.on('unmaximize', () => {
      windowIsMaximized = false;
      webviews.resize();
    });

    ipc.on('enter-full-screen', () => {
      windowIsFullscreen = true;
      webviews.resize();
    });

    ipc.on('leave-full-screen', () => {
      windowIsFullscreen = false;
      webviews.resize();
    });

    // webviews.bindEvent('did-start-navigation', onNavigate);
    // webviews.bindEvent('will-redirect', onNavigate);
    // webviews.bindEvent(
    //   'did-navigate',
    //   function (tabid, url, httpResponseCode, httpStatusText) {
    //     onPageURLChange(tabid, url);
    //   }
    // );

    // webviews.bindEvent('did-finish-load', onPageLoad);

    webviews.bindEvent(
      'page-title-updated',
      (tabid, title, explicitSet) => {
        this.props.dispatch(store.actions.TITLE({ tabid:tabid, title }));
      }
    );

    webviews.bindEvent(
      'did-fail-load',
      (tabid, errorCode, errorDesc, validatedURL, isMainFrame) => {
        this.props.dispatch(store.actions.ERROR({tabid:tabid, errorCode, errorDesc, validatedURL,isMainFrame }));
      }
    );

    webviews.bindEvent('crashed', (tabid, isKilled) => {
      var url = tabs.get(tabid).url;

      tabs.update(tabid, {
        url:
          webviews.internalPages.error +
          '?ec=crash&url=' +
          encodeURIComponent(url),
      });

      // the existing process has crashed, so we can't reuse it
      webviews.destroy(tabid);
      webviews.add({ id: tabid });

      if (tabid === tabs.getSelected()) {
        webviews.setSelected(tabid);
      }
    });

    // webviews.bindIPC('getSettingsData', function (tabid, args) {
    //   var u1=tabs.get(tabid).url;
    //   if (!urlParser.isInternalURL(u1)) {
    //     throw new Error()
    //   }
    //   webviews.callAsync(tabid, 'send', ['receiveSettingsData', settings.list])
    // })
    // webviews.bindIPC('setSetting', function (tabid, args) {
    //   if (!urlParser.isInternalURL(tabs.get(tabid).url)) {
    //     throw new Error()
    //   }
    //   settings.set(args[0].key, args[0].value)
    // })

    // settings.listen(function () {
    //   tasks.forEach(function (task) {
    //     task.tabs.forEach(function (tab) {
    //       if (tab.url.startsWith('file://')) {
    //         try {
    //           webviews.callAsync(tab.id, 'send', ['receiveSettingsData', settings.list])
    //         } catch (e) {
    //           // webview might not actually exist
    //         }
    //       }
    //     })
    //   })
    // })
    webviews.bindIPC('dark-check',  (tab, args, frameId)=> {
      // console.log("dark")
      // console.log("on password-autofill-check")
      webviews.callAsync(tab, 'sendToFrame', [
        frameId,
        'dark',
        this.props.state.dark
      ]);
    });
    webviews.bindIPC('scroll-position-change', (tabid, args) => {
      this.props.dispatch(store.actions.SCROLL({tabid,pos:args[0]}));
    });

    ipc.on('view-event', (e, args) => {
      // console.log("view-event=============================")
      // console.log(args);
      webviews.emitEvent(args.event, args.viewId, args.args);
    });

    ipc.on('async-call-result', (e, args) => {
      webviews.asyncCallbacks[args.callId](args.error, args.result);
      delete webviews.asyncCallbacks[args.callId];
    });

    ipc.on('view-ipc', (e, args) => {
      if (!webviews.viewList.includes(args.id)) {
        // the view could have been destroyed between when the event was occured and when it was recieved in the UI process, see https://github.com/minbrowser/min/issues/604#issuecomment-419653437
        return;
      }
      webviews.IPCEvents.forEach((item) => {
        if (item.name === args.name) {
          // console.log("IPCEvents===========");
          // console.log(args);
          item.fn(args.id, [args.data], args.frameId);
        }
      });
    });

    // setInterval(function() {
    //   captureCurrentTab();
    // }, 30000);

    // ipc.on('captureData', function (e, data) {
    //   previewCache.set(data.id, data.url)
    //   if (data.id === webviews.selectedId && webviews.placeholderRequests.length > 0) {
    //     placeholderImg.src = data.url
    //     placeholderImg.hidden = false
    //   }
    // })

    /* focus the view when the window is focused */

    ipc.on('windowFocus', () => {
      if (
        webviews.placeholderRequests.length === 0 &&
        document.activeElement.tagName !== 'INPUT'
      ) {
        webviews.focus();
      }
    });
    ipc.on('findInPage', () => {
      /* Page search is not available in modal mode. */
      // if (modalMode.enabled()) {
      //   return;
      // }
      this.props.dispatch(store.actions.START_FIND());
    });
    ipc.on('download', () => {
      this.props.dispatch(store.actions.SHOW_DOWNLOAD(true));
    });
    ipc.on('password', () => {
      this.props.dispatch(store.actions.SHOW_PWDVIEW(true));
    });

    ipc.on('inspectPage', () => {
      webviews.callAsync(this.props.state.tabs[this.props.state.tab_value].id, 'toggleDevTools');
    });


    ipc.on('showBookmarks', () => {
      this.props.dispatch(store.partsSlice.actions.SHOW_BOOK(true));
    });

    ipc.on('showHistory', () => {
      this.props.dispatch(store.partsSlice.actions.SHOW_HISTORY(true));
    });

    // ipc.on('duplicateTab',  (e)=> {

    //   browserUI.duplicateTab(state.tabs[state.tab_value].id);
    // });

    ipc.on('addTab', (e, data) => {
      this.props.dispatch(store.actions.ADD_TAB(data));
    });
    console.log('on saveCurrentPage=======================');
    ipc.on('saveCurrentPage', () => {
      console.log('saveCurrentPage==========');
      console.log(window.myAPI);
      var currentTab = state.tabs[state.tab_value];
      // new tabs cannot be saved
      if (!currentTab.url) {
        return;
      }
      // if the current tab is a PDF, let the PDF viewer handle saving the document
      // if (PDFViewer.isPDFViewer(window.tasklist.task.tabs.getSelected())) {
      //   PDFViewer.savePDF(window.tasklist.task.tabs.getSelected());
      //   return;
      // }
      // ipc.send("savedlg", {
      //       defaultPath: currentTab.title.replace(/[/\\]/g, '_')
      // });
      // ipc.once('savedlg_res', (e,res) => {
      //     console.log(e);
      //     console.log(res);
      //     if (!res) return;
      //     if(res.canceled) return;
      //       let savePath=res.filePath;
      //       if (!savePath.endsWith('.html')) {
      //         savePath = savePath + '.html'
      //       }
      //       webviews.callAsync(tabs.getSelected(), 'savePage', [savePath, 'HTMLComplete'])
      // });
      var options = {
        // defaultPath: 'bookmarks.html',
        filters: [{ name: 'HTML files', extensions: ['htm', 'html'] }],
      };
      electron.ipcRenderer
        .invoke('showSaveDialog', options)
        .then((res) => {
          console.log(res);
          if (!res) return;
          let savePath = res;
          webviews.callAsync(state.tabs[state.tab_value].id, 'savePage', [
            savePath,
            'HTMLComplete',
          ]);
          // window.require('fs').writeFileSync(savePath, root.outerHTML);
          // console.log(e);
          // console.log(res);
          // if (!res) return;
          // if(res.canceled) return;
          // let savePath=res.filePath;
          // if (!savePath.endsWith('.html')) {
          //   savePath = savePath + '.html'
          // }
          // webviews.callAsync(tabs.getSelected(), 'savePage', [savePath, 'HTMLComplete'])
        })
        .catch((e) => {
          console.log(e);
        });
    });
    // ipc.on('addPrivateTab',  ()=> {
    //   browserUI.addTab(
    //     window.tasklist.task.tabs.add({
    //       private: true,
    //     })
    //   );
    // });
    ipc.on('goBack', () => {
      webviews.callAsync(this.props.state.tabs[this.props.state.tab_value].id, 'goBack');
    });

    ipc.on('goForward', () => {
      webviews.callAsync(this.props.state.tabs[this.props.state.tab_value].id, 'goForward');
    });
    // ipc.on('openPDF', (event, data)=>{

    //   // this.props.dispatch(store.partsSlice.actions.OPEN_PDF(data));
    // });
    ipc.on('request_close', () => {
      this.props.dispatch(store.partsSlice.actions.SAVE());
      ipc.send("close");
    });
    ipc.on('zoomIn', () => {
      webviews.zoomWebviewIn(this.props.state.tabs[this.props.state.tab_value].id);
    });

    ipc.on('zoomOut', () => {
      webviews.zoomWebviewOut(this.props.state.tabs[this.props.state.tab_value].id);
    });

    ipc.on('zoomReset', () => {
      webviews.resetWebviewZoom(this.props.state.tabs[this.props.state.tab_value].id);
    });

    ipc.on('print', () => {
      webviews.callAsync(
        this.props.state.tabs[this.props.state.tab_value].id,
        'executeJavaScript',
        'window.print()'
      );
    });
    //must before view created
    webviews.bindEvent('context-menu', (tabid, data) => {
      console.log("context-menu----------------")
      this.menuData = data;
      webviews.callAsync(tabid, 'send', [
        'getContextMenuData',
        { x: data.x, y: data.y },
      ]);
    });
    webviews.bindIPC('contextMenuData', (tabid, args) => {
      console.log('contextMenuData');
      this.showMenu(this.props.state.tabs[this.props.state.tab_value], this.menuData, args[0]);
      this.menuData = null;
    });
    if (places.worker) {
      places.worker.terminate();
    }
    places.worker = new Worker('esbuild/placesWorker.js');
    places.worker.onmessage = places.onMessage;
    webviews.bindIPC('pageData', (tabid, data) => {
      places.receiveHistoryData(this.props.state.tabs[this.props.state.tab_value], data);
    });
    webviews.bindEvent('media-started-playing', (tabId)=> {
      console.log("hasAudio true")
      // webviews.callAsync(tabid, 'setAudioMuted', false);
      this.props.dispatch(store.partsSlice.actions.HAS_AUDIO({tabid,hasAudio:true}));
    })
    webviews.bindEvent('media-paused', (tabid)=> {
      this.props.dispatch(store.partsSlice.actions.HAS_AUDIO({tabid,hasAudio:false}));
      console.log("hasAudio false")
    })
    checkSettings: () => {
      let manager = PasswordManager.getActivePasswordManager();
      if (!manager) {
        return;
      }
    },
    SearchBar.register('simpleBookmarkTagInput', {
      index: 0,
    });

    //
    webviews.bindEvent('did-navigate', (tabid, url) => {
      this.props.dispatch(store.partsSlice.actions.NAVIGATE({ tabid: tabid, url: url }));
      this.update_goback(tabid, url);
    });
    //todo tabBar.update_goback
    webviews.bindEvent('did-navigate-in-page', this.update_goback);
    ipc.on('preferences', () => {
      this.props.dispatch(store.partsSlice.actions.SHOW_SETTING(true));
    });
    ipc.on('about_click', (e, data) => {
      console.log(data);
    });
    /* progress bar events */

    webviews.bindEvent('did-start-loading', (tabid) => {
      let i;
      for (i = 0; i <this.props.state.tabs.length; i++) {
        if (this.props.state.tabs[i].id == tabid) {
          // this.props.state.tabs[i].status = 'start';
          this.props.dispatch(store.partsSlice.actions.TAB_STATUS({index:i,status:'start'}));
          break;
        }
      }
    });

    webviews.bindEvent('did-stop-loading', (tabid) => {
      let i;
      for (i = 0; i < this.props.state.tabs.length; i++) {
        if (this.props.state.tabs[i].id == tabid) {
          // this.props.state.tabs[i].status = 'finish';
          this.props.dispatch(store.partsSlice.actions.TAB_STATUS({index:i,status:'finish'}));
          break;
        }
      }
      console.log('did-stop-loading');
      // this.props.dispatch(store.partsSlice.actions.UPDATE_TABS());
    });

    webviews.bindEvent(
      'new-window',
      (tabid, url, frameName, disposition) => {
        this.props.dispatch(store.partsSlice.actions.ADD_TAB({ url }));
        // this.props.dispatch(store.partsSlice.actions.NEW_WINDOW());
        /* disabled in focus mode */
      }
    );

    webviews.bindIPC('close-window', (tabid, args) => {
      this.props.dispatch(store.partsSlice.actions.CLOSE_TAB_ID(tabid));
    });
    // webviews.bindEvent('view-hidden', function (tabid) {
    //   if (tabid === Findinpage.activeTab) {
    //     Findinpage.end();
    //   }
    // });

    // webviews.bindEvent(
    //   'did-start-navigation',
    //   function (
    //     tabid,
    //     url,
    //     isInPlace,
    //     isMainFrame,
    //     frameProcessId,
    //     frameRoutingId
    //   ) {
    //     if (!isInPlace && tabid === Findinpage.activeTab) {
    //       Findinpage.end();
    //     }
    //   }
    // );

    webviews.bindEvent('found-in-page', (tabid, data) => {
      if (data.matches !== undefined) {
        var text;
        if (data.matches === 1) {
          text = l('findMatchesSingular');
        } else {
          text = l('findMatchesPlural');
        }
        this.props.dispatch(store.partsSlice.actions.UPDATE_COUNT(text
          .replace('%i', data.activeMatchOrdinal)
          .replace('%t', data.matches)));
        // Findinpage.updateCount(
        //   text
        //     .replace('%i', data.activeMatchOrdinal)
        //     .replace('%t', data.matches)
        // );
      }
    });
    settings.list = ipc.sendSync('getSettingsData');

    ipc.on('receiveSettingsData', function(e, data) {
      settings.list = data;
      settings.runChangeCallacks();
    });
    settings.listen('passwordManager', (manager) => {
        if (manager) {
          // Trigger the check on browser launch and after manager is enabled
          this.checkSettings();
        }
      });
    // console.log('//////////// passwordManager initialize');
    // Called when page preload script detects a form with username and password.
    webviews.bindIPC('password-autofill', (tab, args, frameId)=>{
      console.log('PasswordManager==');
      console.log('on password-autofill');
      // We expect hostname of the source page/frame as a parameter.
      if (args.length == 0) {
        return;
      }
      const hostname = args[0];

      PasswordManager.getConfiguredPasswordManager().then(async (manager) => {
        if (!manager) {
          return;
        }

        if (!manager.isUnlocked()) {
          await PasswordManager.unlock(manager);
        }

        var domain = hostname;
        if (domain.startsWith('www.')) {
          domain = domain.slice(4);
        }

        manager
          .getSuggestions(domain)
          .then((credentials) => {
            if (credentials != null) {
              webviews.callAsync(tab, 'getURL', function (err, topLevelURL) {
                if (err) {
                  console.warn(err);
                  return;
                }
                var topLevelDomain = new URL(topLevelURL).hostname;
                if (topLevelDomain.startsWith('www.')) {
                  topLevelDomain = topLevelDomain.slice(4);
                }
                if (domain !== topLevelDomain) {
                  console.warn("autofill isn't supported for 3rd-party frames");
                  return;
                }
                webviews.callAsync(tab, 'sendToFrame', [
                  frameId,
                  'password-autofill-match',
                  {
                    credentials,
                    hostname,
                  },
                ]);
              });
            }
          })
          .catch((e) => {
            console.error('Failed to get password suggestions: ' + e.message);
          });
      });
    });
    webviews.bindIPC('password-autofill-check', function (tab, args, frameId) {
      // console.log("PasswordManager==")
      // console.log("on password-autofill-check")
      if (PasswordManager.getActivePasswordManager()) {
        webviews.callAsync(tab, 'sendToFrame', [
          frameId,
          'password-autofill-enabled',
        ]);
      }
    });
    // keybindings.defineShortcut('fillPassword', function () {
    //   webviews.callAsync(tabs.getSelected(), 'send', [
    //     'password-autofill-shortcut',
    //   ]);
    // });
    webviews.bindIPC(
      'password-form-filled',
      PasswordCapture.handleRecieveCredentials
    );
    ro.observe(this.ref_target.current); // Watch dimension changes on body
    this.props.dispatch(store.sessionRestoreAction());
  }
  render() {
    // console.log('render Browser===========');
    // console.log(this.props);
    return (
      <ThemeProvider theme={darkTheme}>
        <div ref={this.ref_target}>
          <TabBar state={this.props.state} dispatch={this.props.dispatch} />
        </div>
      </ThemeProvider>
    );
  }
}
const mapStateToProps = (state) => {
  // console.log("mapStateToProps=========")
  // console.log(state);
  return { state: state };
}
export default connect(mapStateToProps)(Browser);